/*
 * gtk_ed.c
 *
 * Copyright (C) 2012 CADCAM-Servies Franz Reiter (franz.reiter@cadcam.co.at)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *


-----------------------------------------------------
Editorwindowtools for GTK2.    2005-01-07     RF

TODO:
  GUI_Ed_Init sollte ein GUI_obj zurueckgeben; eine struct in der der typ
    und alle notwendigen Objekte enthalten sind.

  // GraficInterfaceObject  EditorWindow
typedef struct {GtkWidget *view,
                GtkTextBuffer *text,
                GtkWidget *pack}                                   GIO_WinEd


-----------------------------------------------------
Modifications:
2012-03-10 port Gtk3. RF.
2005-01-07 neu; nur f. GTK2; was ut_gtkEd.c f GTK1. RF.

-----------------------------------------------------
*//*!
\file ../gtk/gtk_ed.c
\ingroup grp_gui
\code

=====================================================
Liste_Funktionen_Beginn:

GUI_Ed_getLsta       get ZeilenStartPos as Offset
GUI_Ed_getLend       get ZeilenEndPos as Offset
GUI_Ed_getLpos       get ZeilenStart/EndPos as Offsets
GUI_Ed_getEof        get EOF-Position as Offset
GUI_Ed_getCpos       get Cursorposition as Offset
GUI_Ed_getLnr        get LineNr of act.Curpos

GUI_Ed_setCpos       Cursorposition setzen (= implizites unselect)
GUI_Ed_setCnxtL      Cursorposition auf next Line setzen
GUI_Ed_scroll_u      scroll to curPos (= implizites unselect)
GUI_Ed_scroll_s      scroll to curPos (= selected)

GUI_Ed_sel__         select_region
GUI_Ed_sel_ln        select Line, set Curpos to Line.

GUI_Ed_Insert        Text einfuegen
GUI_Ed_Ins_f         Inhalt einer Datei einfuegen und selected setzen
GUI_Ed_Write         das gesamte Editfenster neu schreiben (txbuf -> Window)

GUI_Ed_RdChr         read char near cursor
GUI_Ed_RdLnAct       die aktuelle Zeile einlesen
GUI_Ed_Read          Den Windowinhalt -> txbuf kopieren.
GUI_Ed_sel_wrf       write selected text -> file

GUI_Ed_sel_del       delete select_region
GUI_Ed_del           delete Bereich von - bis

GUI_Ed_Init          Create ein Editfenster.
GUI_Ed_Init1         get attributes of Editwindow (textsize, ..)
GUI_Ed_Focus         den Focus auf EditWindopw
GUI_Ed_editable      editabel or frozen ..
 
GUI_Ed_update_txt    refresh txt

Liste_Funktionen_Ende:
=====================================================

\endcode *//*----------------------------------------



cc -c `pkg-config --cflags gtk+-3.0` -DGTK3 gtk_ed.c

*/


#include "../xa/MS_Def0.h"

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#include <gtk/gtk.h>

#include "../gui/gui_types.h"      // UI_Func..

#include "../gui_gtk/gtk_ed.h"


// #include "../gtk/ut_gtk.h"
// #include "../gtk/ut_gtkEd.h"
// #include "../ut/ut_txfil.h"                   // UTF_GetPosLnr


// static int   UI_Ed_ln_sizY;      UNUSED
// static float UI_Ed_ln_offY;      UNUSED
static char  *UI_Ed_lcSet;     // Pointer to locale charSet; NULL if UTF8 !




//================================================================
  int GUI_Ed_editable (GIO_WinEd *wTx, int mode) {
//================================================================
/// \code
/// GUI_Ed_editable      editabel or frozen ..
/// mode: FALSE = 0 TRUE  = 1
/// ACHTUNG: tw abhaengig vom style; see UI_MainWin/UI_styl_1
/// \endcode

  printf("GUI_Ed_editable %d\n",mode);

// GEHT SCHEINBAR NUR VOR DEM OPEN WINDOW ..
  // gtk_text_view_set_editable (GTK_TEXT_VIEW (wTx->view),  FALSE);

  // gtk_editable_set_editable ((GtkEditable*)wTx->view, FALSE);
  // geht ned, `GTK_IS_EDITABLE (editable)' failed

  gtk_widget_set_sensitive (wTx->view,  mode);


  return 0;

}



//==========================================================================
  int GUI_Ed_getLsta  (GIO_WinEd *wTx, int cPos) {
//==========================================================================
/// get startPos of Line,  cPos is CurPos in Line.

  GtkTextIter it1;
  int         lNr, cpos1;

  // get iter from offset
  gtk_text_buffer_get_iter_at_offset (wTx->text, &it1, cPos);

  // get LineNr from iter
  lNr = gtk_text_iter_get_line (&it1);

  // get iter at startPos of line from LineNr
  gtk_text_buffer_get_iter_at_line (wTx->text, &it1, lNr);

  // offset from iter
  cpos1 = gtk_text_iter_get_offset (&it1);

  // printf("ex GUI_Ed_getLsta %d %d %d\n",cpos1,cPos,lNr);

  return cpos1;

}



//==========================================================================
  int GUI_Ed_getLend  (GIO_WinEd *wTx, int cPos) {
//==========================================================================
/// get endingPos of Line,  cPos is CurPos in Line.


  GtkTextIter it1;
  int         lNr, cpos1;

  // get iter from offset
  gtk_text_buffer_get_iter_at_offset (wTx->text, &it1, cPos);

  // get LineNr from iter
  lNr = gtk_text_iter_get_line (&it1);

  // get iter at startPos of line from LineNr
  gtk_text_buffer_get_iter_at_line (wTx->text, &it1, lNr+1);

  // offset from iter
  cpos1 = gtk_text_iter_get_offset (&it1);

  --cpos1;

  // printf("ex GUI_Ed_getLend %d %d %d\n",cpos1,cPos,lNr);

  return cpos1;


}


//==========================================================================
  long GUI_Ed_getEof (GIO_WinEd *wTx) {
//==========================================================================
/// GUI_Ed_getEof      get FileSize (EOF-Position)


  long fSiz;

  // fSiz = gtk_text_get_length ((GtkText*)widget);

  // get nr of chars in buffer
  fSiz = gtk_text_buffer_get_char_count (wTx->text);

  // printf("ex GUI_Ed_getEof %d\n",fSiz);

  return fSiz;

}


//================================================================
  int GUI_Ed_getLnr (GIO_WinEd *wTx) {
//================================================================
/// \code
/// GUI_Ed_getLnr        get LineNr of act.Curpos
/// ACHTUNG: use always GUI_Ed_getLnr (not GUI_Ed_getLnr); 
///  die Filesize und cPos ist unterschiedlich, weil gtk Sonderzeichen nur
///  als 1 char behandelt !!!
/// Man darf daher die cPos nicht zum Positionieren im Mem benutzen !!!!
/// \endcode

  int         lNr;
  GtkTextMark *mk1;
  GtkTextIter it1;

  // printf("GUI_Ed_getLnr \n");

  // get mark at CurPos
  mk1 = gtk_text_buffer_get_mark (wTx->text, "insert");

  // iter at CurPos
  gtk_text_buffer_get_iter_at_mark (wTx->text, &it1, mk1);


  // get LineNr from iter
  lNr = gtk_text_iter_get_line (&it1);

  // gCAd beginnt mit LineNr 1 !!!
  ++lNr;

  // // offset from iter
  // cpos1 = gtk_text_iter_get_offset (&it1);


    // printf("ex GUI_Ed_getLnr %d\n",lNr);

  return lNr;

}


//==========================================================================
  long GUI_Ed_getCpos (GIO_WinEd *wTx) {
//==========================================================================
/// \code
/// cpos = offset vom Dateianfang in anz char
/// cpos -> Zeilennummer: UTF_GetLnrPos
/// \endcode

  GtkTextMark *mk1;
  GtkTextIter it1;

  long cpos;

  // printf("GUI_Ed_getCpos \n");

  // get mark at CurPos
  mk1 = gtk_text_buffer_get_mark (wTx->text, "insert");

  // iter at CurPos
  gtk_text_buffer_get_iter_at_mark (wTx->text, &it1, mk1);

  // get offset of CurPos
  cpos = gtk_text_iter_get_offset (&it1);

  // printf("ex GUI_Ed_getCpos %d\n",cpos);

  return cpos;

}


//================================================================
  int GUI_Ed_setLnr (GIO_WinEd *wTx, long lNr) {
//================================================================
 
  GtkTextIter it1;

  printf("GUI_Ed_setLnr %ld\n",lNr);

  
  // set iter from lNr
  gtk_text_buffer_get_iter_at_line (wTx->text, &it1, lNr);

  // moves the "insert" and "selection_bound" marks simultaneously
  gtk_text_buffer_place_cursor (wTx->text, &it1);

  // scroll & focus
  GUI_Ed_scroll_s (wTx);


  return 0;

}


//==========================================================================
  int GUI_Ed_setCpos (GIO_WinEd *wTx, long cpos) {
//==========================================================================
/// Cursorposition setzen und Focus auf EditWin

  GtkTextIter it1;

  // printf("GUI_Ed_setCpos %d\n",cpos);

  // set iter from cpos
  gtk_text_buffer_get_iter_at_offset (wTx->text, &it1, cpos);

  // moves the "insert" and "selection_bound" marks simultaneously
  gtk_text_buffer_place_cursor (wTx->text, &it1);

  // scroll & focus
  GUI_Ed_scroll_s (wTx);


  return 1;

}


//==========================================================================
  int GUI_Ed_setCnxtL (GIO_WinEd *wTx) {
//==========================================================================
/// GUI_Ed_setCnxtL      Cursorposition auf next Line

  GtkTextIter it1, it2;

  printf("GUI_Ed_setCnxtL\n");

  // get get iters for "insert" & "selection_bound"
  gtk_text_buffer_get_selection_bounds (wTx->text, &it1, &it2);

  // move iter to next line
  gtk_text_iter_forward_line (&it1);

  // moves the "insert" and "selection_bound" marks simultaneously
  gtk_text_buffer_place_cursor (wTx->text, &it1);

  // scroll & focus
  GUI_Ed_scroll_s (wTx);

  return 1;

}



//==========================================================================
  int GUI_Ed_getLpos  (int *sPos, int *ePos, int cPos, GIO_WinEd *wTx) {
//==========================================================================
/// get starting & endingPos of Line; cPos is CurPos in Line.


  int   cpos1, cpos2;



    // den Zeilenstart suchen; zurueck bis zum LF.
    cpos1 = GUI_Ed_getLsta (wTx, cPos);

    // find end of Line
    cpos2 = GUI_Ed_getLend (wTx, cPos);


  Fertig:
  *sPos = cpos1;
  *ePos = cpos2;

  // printf("ex GUI_Ed_getLpos %d - %d / %d\n",cpos1,cpos2,cPos);

  return 0;


}


//================================================================
  int GUI_Ed_scroll_u (GIO_WinEd *wTx, int cPos) {
//================================================================
/// impliziert unselect


  GtkTextIter it1, it2;

  // printf("GUI_Ed_scroll_u %d\n",cPos);


  // get iters for "insert" & "selection_bound"
  gtk_text_buffer_get_selection_bounds (wTx->text, &it1, &it2);


  // moves the "insert" and "selection_bound" marks simultaneously
  gtk_text_buffer_place_cursor (wTx->text, &it1);


  return 0;

}

//================================================================
  int GUI_Ed_scroll_s (GIO_WinEd *wTx) {
//================================================================
/// macht leider ein unselect !!

  GtkTextMark *mk1;
  GtkTextIter it1;

  // printf("GUI_Ed_scroll_s \n");


  // scroll to insert-mark:
  mk1 = gtk_text_buffer_get_mark (wTx->text, "insert");

  // gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW(wTx->view), &it1,
  gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (wTx->view), mk1,
     0.1,              // within_margin
     FALSE,            // use_align
     0.5, 0.0);        // xalign,yalign


  // ohne foc selection nicht sichbar !!
  GUI_Ed_Focus (wTx);


  return 0;

}


//================================================================
  int GUI_Ed_sel__ (GIO_WinEd *wTx, int von, int bis) {
//================================================================
/// \code
/// select_region von cpos bis cpos (und scroll!)
/// if(von < 0)  - unsect all !
/// \endcode

  GtkTextIter it1;
  GtkTextMark *mk1;


  // printf("GUI_Ed_sel__ %d %d\n",von,bis);


  // get iter from offset
  gtk_text_buffer_get_iter_at_offset (wTx->text, &it1, von);

  // move "insert" & "selection_bound"-marks
  gtk_text_buffer_place_cursor (wTx->text, &it1);

/*
  // nach "von" scrollen"
  gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW(wTx->view), &it1,
     0.1,              // within_margin
     FALSE,            // use_align
     0.5, 0.0);        // xalign,yalign
*/

  // get iter from offset
  gtk_text_buffer_get_iter_at_offset (wTx->text, &it1, bis);

  // gtk_text_buffer_get_iter_at_offset (wTx->text, &it1, bis);
  // gtk_text_buffer_move_mark_by_name (wTx->text, "insert", &it1);

  // set end - mark
  gtk_text_buffer_move_mark_by_name (wTx->text, "selection_bound", &it1);



/*
  // scroll to insert-mark:
  mk1 = gtk_text_buffer_get_mark (wTx->text, "insert");

  gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (wTx->view), mk1,
     0.1,              // within_margin
     FALSE,            // use_align
     0.5, 0.0);        // xalign,yalign
*/


  return 0;
}



//================================================================
  int GUI_Ed_sel_ln (GIO_WinEd *wTx, long lNr) {
//================================================================
/// \code
/// GUI_Ed_sel_ln         select Line, set Curpos to Line.
/// Erste Zeile ist 1
/// rc -1: lNr does not exist
/// ACHTUNG: die ZeilenStart/Endposition wird aus dem mem gelesen !!!!
/// \endcode

  int   i1;
  GtkTextIter it1;


  // printf("GUI_Ed_sel_ln %d\n",lNr);

  --lNr;

  // get nr of lines
  i1 = gtk_text_buffer_get_line_count (wTx->text) - 1;
  // printf(" lMax=%d\n",i1);
  if(i1 <= lNr) {
    gtk_text_buffer_get_iter_at_line (wTx->text, &it1, i1);
    gtk_text_buffer_place_cursor (wTx->text, &it1);
    return -1;
  }


  // get Iter at Linestart
  gtk_text_buffer_get_iter_at_line (wTx->text, &it1, lNr);

  // move "insert" & "selection_bound"-marks
  gtk_text_buffer_place_cursor (wTx->text, &it1);


  // get Iter at start of next Line
  gtk_text_buffer_get_iter_at_line (wTx->text, &it1, lNr+1);

  // set mark
  gtk_text_buffer_move_mark_by_name (wTx->text, "selection_bound", &it1);



  // scroll & focus
  GUI_Ed_scroll_s (wTx);


/*
  int    i1, i2;
  long   ll;
  char   *p1, *p2;

  // Ablauffehler in MAN; set CurPos, select act. Line.
        p1 = UTF_GetPosLnr (&ll, lNr);
        if(p1 == NULL) return -1;
        p2 = UTF_GetnextLnPos (p1);
        // Startposition der zeile abfragen
        i1 = UTF_offset_ (p1);
        i2 = UTF_offset_ (p2);
        // GUI_Ed_setCpos (wText, i2);
        // Zeile selektiert darstellen; setzt auch curPos.
        GUI_Ed_sel__ (wTx, i1, i2);
*/


  return 0;

}



/*==========================================================================*/
  int GUI_Ed_sel_del (GIO_WinEd *wTx) {
/*==========================================================================*/
/// delete selected text

  printf("GUI_Ed_sel_del \n");

  gtk_text_buffer_delete_selection (wTx->text, TRUE, TRUE);

  return 0;

}


//================================================================
  int GUI_Ed_del (GIO_WinEd *wTx, int von, int bis) {
//================================================================

  GtkTextIter it1, it2;
  int         txlen;


  // printf("GUI_Ed_del %d %d %d\n",von,bis,txlen);


  // get nr of chars in buffer
  txlen = gtk_text_buffer_get_char_count (wTx->text);


  if(von >= txlen) return -1;
  if(bis > txlen) bis = txlen;

  // set iter from cpos
  gtk_text_buffer_get_iter_at_offset (wTx->text, &it1, von);
  gtk_text_buffer_get_iter_at_offset (wTx->text, &it2, bis);

  // del
  gtk_text_buffer_delete (wTx->text, &it1, &it2);


  // // den Cursor noch in die naechste zeile bewegen
  // cpos = von + 1;
  // // gtk_editable_set_position ((GtkEditable*)text, cpos);
  // GUI_Ed_scroll_u (text, cpos);

  return 0;

}


//================================================================
  int GUI_Ed_sel_wrf (GIO_WinEd *wTx, char *fnam) {
//================================================================
/// \code
/// write selected -> file
/// returns nr of chars
/// \endcode

  GtkTextIter it1, it2;
  int  i1;
  char *text;
  FILE *fpo;


  // printf("GUI_Ed_sel_wrf |%s|\n",fnam);


  if((fpo=fopen(fnam,"wb")) == NULL) {
    TX_Print("GUI_Ed_sel_wrf E001 |%s|",fnam);
    return -1;
  }


  // get get iters for "insert" & "selection_bound"
  gtk_text_buffer_get_selection_bounds (wTx->text, &it1, &it2);

  // get text
  text = gtk_text_iter_get_text (&it1, &it2);
  printf("/%s/\n",text);

  i1 = strlen(text);

  fwrite(text, i1, 1, fpo);

  g_free (text);

  fclose(fpo);

  return i1;

}


//===========================================================================
  int GUI_Ed_Insert (GIO_WinEd *wTx, int cpos, char* txbuf, long txlen) {
//===========================================================================
/// \code
/// text einfuegen
/// cpos zB von GUI_Ed_getCpos
/// \endcode

  GtkTextIter it1;

  // printf("GUI_Ed_Insert %d %d |%s|\n",cpos,txlen,txbuf);

  // get iter from offset
  gtk_text_buffer_get_iter_at_offset (wTx->text, &it1, cpos);

  // insert at iterPos
  gtk_text_buffer_insert (wTx->text, &it1, txbuf, -1);


  return 0;

}


//==========================================================================
  char GUI_Ed_RdChr (GIO_WinEd *wTx, int offset) {
//==========================================================================
/// \code
/// read char near cursor;
/// offset  0 = char right of cursor
/// offset -1 = char left of cursor
/// returns  '\0' for out-of-file-positions.
/// \endcode

  GtkTextMark *mk1;
  GtkTextIter it1;
  gboolean    b1;
  char        c1;


  // printf("GUI_Ed_RdChr |%c| %d\n",c1,cpos);

  // get mark at CurPos
  mk1 = gtk_text_buffer_get_mark (wTx->text, "insert");

  // iter at CurPos
  gtk_text_buffer_get_iter_at_mark (wTx->text, &it1, mk1);

  // move iter back
  if(offset < 0) {
    b1 = gtk_text_iter_backward_chars (&it1, -offset);
    // false if left of 1. char; returns Null !.
    if(b1 == FALSE) return '\0';
  }

  // move iter forw
  if(offset > 1) {
    b1 = gtk_text_iter_forward_chars (&it1, offset);
    // false if left of 1. char; returns Null !.
    if(b1 == FALSE) return '\0';
  }


  // get char at curpos
  c1 = gtk_text_iter_get_char (&it1);

  // printf("ex GUI_Ed_RdChr |%c|\n",c1);

  return c1;

}


//==========================================================================
  int GUI_Ed_RdLnAct (GIO_WinEd *wTx, char* txbuf, int *txlen) {
//==========================================================================
/// \code
/// die aktuelle Zeile aus dem Editor einlesen
/// Input:
///   txlen    size of txbuf
/// Output:
///   txlen    length of string in txbuf
/// \endcode

// Problem ! max 256 chars from ED_query_CmdMode ..


  int         llen, lNr, lTot;
  GtkTextIter it1, it2;
  char        *text;

  // printf("GUI_Ed_RdLnAct\n");


  // get get iters for "insert" & "selection_bound"
  gtk_text_buffer_get_selection_bounds (wTx->text, &it1, &it2);

  // get LineNr from iter
  lNr = gtk_text_iter_get_line (&it1);
  // printf(" lNr=%d\n",lNr);


  // get highest Linenr (0=first)
  lTot = gtk_text_buffer_get_line_count (wTx->text) - 1;
  // printf(" lTot=%d\n",lTot);

  // get linestart.
  gtk_text_buffer_get_iter_at_line (wTx->text, &it1, lNr);

  // wenn it1 am EOF!   MACHT FEHLER !!!
  // if(gtk_text_iter_is_end(&it1) == TRUE) {   // MACHT AUCH MIST !!!
  if(lNr == lTot) {   // MACHT AUCH MIST !!!
    // printf(" LETZTE ZEILE !!\n");
    gtk_text_buffer_get_end_iter (wTx->text, &it2);

  } else {
    // get lineend
    gtk_text_buffer_get_iter_at_line (wTx->text, &it2, lNr+1);
  }

  // text = gtk_text_buffer_get_text (actBuf, &start, &end, FALSE);
  text = gtk_text_iter_get_text (&it1, &it2);
  llen = strlen(text);
  if(llen > *txlen) llen = *txlen - 1;
  strncpy(txbuf, text, llen);
  txbuf[llen] = '\0';
  g_free (text);


  *txlen = llen;

  // remove CR-LF
  if(llen > 0) {
    --llen;
    if(txbuf[llen] == '\n') {
      txbuf[llen] = '\0';
      *txlen -= 1;
    }
  }



  // printf("ex GUI_Ed_RdLnAct |%s| %ld\n",txbuf,*txlen);

  return 1;
}


//================================================================
  int GUI_Ed_Ins_f (GIO_WinEd *wTx, char *fnam) {
//================================================================
/// GUI_Ed_Ins_f         Inhalt einer datei einfuegen und selected setzen.

  GtkTextIter it1, it2;
  int  i1, i2;
  char c1;
  FILE *fpi;


  printf("GUI_Ed_Ins_f |%s|\n",fnam);


  if((fpi=fopen(fnam,"rb")) == NULL) {
    TX_Print("GUI_Ed_Ins_f E001 |%s|",fnam);
    return -1;
  }

  // // get get iters for "insert" & "selection_bound"
  // gtk_text_buffer_get_selection_bounds (wTx->text, &it1, &it2);
  // // insert at iterPos
  // gtk_text_buffer_insert (wTx->text, &it1, txbuf, -1);


  i1 = GUI_Ed_getCpos (wTx);
    printf(" i1=%d\n",i1);

  while(fread(&c1,1,1,fpi)) {
    printf("%c",c1);
    gtk_text_buffer_insert_at_cursor (wTx->text, &c1, 1);
  }
    printf("\n");
  fclose(fpi);

  i2 = GUI_Ed_getCpos (wTx);
    printf(" cpos=i2=%d\n",i2);

  // select region i1 - i2
  GUI_Ed_sel__  (wTx, i1, i2);

  return 0;

}


//================================================================
  int GUI_Ed_Read (GIO_WinEd *wTx, char* txbuf, long *txlen) {
//================================================================
/// \code
/// Den gesamten Windowinhalt -> txbuf kopieren.
/// Input: txlen = maxlen of txbuf!
/// \endcode


  int         irc, i1, fSiz, maxLen;
  char        *text;
  long        cpos;
  GtkTextIter start, end;


  // printf("GUI_Ed_Read siz=%d\n",*txlen);

  maxLen = *txlen;

  // query active CurPos
  cpos = GUI_Ed_getCpos (wTx);
    // printf(" _Ed_Read cpos=%d\n",cpos);


  // get iters at start, end
  gtk_text_buffer_get_bounds (wTx->text, &start, &end);

  // text = gtk_text_buffer_get_text (actBuf, &start, &end, FALSE);
  text = gtk_text_iter_get_text (&start, &end);

  // // get nr of chars in buffer
  // fSiz = gtk_text_buffer_get_char_count (wTx->text);
    // printf(" _Ed_Read1=%d\n",fSiz);

  // -wirkliche Size ist wgen UTF groesser !!!
  fSiz = strlen(text);
    // printf(" _Ed_Read2=%d\n",fSiz);


  if(fSiz < maxLen) {
    // copy out
    strncpy(txbuf, text, fSiz);
    txbuf[fSiz] = '\0';
    *txlen = fSiz;
    // *txlen = strlen(txbuf);
    irc = 0;

  } else {
    *txlen = fSiz;
    irc = -1;
  }

  g_free (text);

/*
  // alle Umlaute entsorgen:
  i1 = UTX_ck_uml_s (txbuf, txlen, maxLen);
  // wurden Umlaute gefunden, retour in den Editor
  if(i1 > 0) GUI_Ed_Write (wTx, txbuf, *txlen);
*/




  // ein refresh Window notwendig !
  // GUI_Ed_Focus (wTx);  hilft nix ..
  // GUI_Ed_scroll_u (wTx, 300);  hilft nix ..
  // GUI_Ed_sel__ (wTx, 300, 303);  // das geht !!
  // GUI_Ed_sel__ (wTx, cpos-3, cpos); geht aa ned ..
  // // gtk_text_buffer_move_mark_by_name (wTx->text, "selection_bound", &end);
  // GUI_Ed_scroll_s (wTx); // hilft nix ..
  // gtk_widget_map (wTx->text);
  // gtk_widget_set_sensitive (wTx->text, FALSE);
  // while (gtk_events_pending()) gtk_main_iteration();


  // die folgenden Zeilen machen nur eine Displayupdate;
  // sonst steht leider Mist im Fenster ...
  GUI_Ed_update_txt (wTx, cpos);


  // printf("ex GUI_Ed_Read %d\n",*txlen);
  // printf("ex GUI_Ed_Read %d\n",*txlen);
  // printf("|"); UTX_dump_s__(txbuf,*txlen+1);printf("|");

  return irc;

}


//================================================================
  int GUI_Ed_update_txt (GIO_WinEd *wTx, long cpos) {
//================================================================
/// make Displayupdate;
 
  GtkTextIter it1;

  // printf("GUI_Ed_update_txt %d\n",cpos);


  // die folgenden Zeilen machen nur eine Displayupdate;
  // sonst steht leider Mist im Fenster ...
  gtk_text_buffer_get_iter_at_offset (wTx->text, &it1, 0);
  gtk_text_buffer_place_cursor (wTx->text, &it1);
  // gtk_text_buffer_move_mark_by_name (wTx->text, "selection_bound", &it1);
  // gtk_text_view_place_cursor_onscreen (wTx->view);

  gtk_text_buffer_get_iter_at_offset (wTx->text, &it1, cpos);
  gtk_text_buffer_place_cursor (wTx->text, &it1);
  // gtk_text_buffer_move_mark_by_name (wTx->text, "selection_bound", &it1);
  // gtk_text_view_place_cursor_onscreen (wTx->view);
  GUI_Ed_scroll_s (wTx); // hilft nix ..



  return 0;

}


//===========================================================================
  int GUI_Ed_Write (GIO_WinEd *wTx, char* txbuf, long *txlen, long maxlen) {
//===========================================================================
/// \code
/// das gesamte Editfenster neu schreiben (txbuf(=mem) -> Window).
/// ACHTUNG: GUI_Ed_Write kann txbuf veraendern ! (Umwandlung into UTF8)
/// \endcode

  int         i1, i2;
  char        *p1;
  GtkTextIter it1;


  // printf("GUI_Ed_Write %ld\n",*txlen);
  // printf("|"); UTX_dump_s__(txbuf,*txlen+1);printf("|");
  // UTF_dump__ ();


  // test if input is valid UTF8; 1==OK, 0=must_convert.
  if(UI_Ed_lcSet) {
    i1 = g_utf8_validate (txbuf, *txlen, (const gchar **)&p1);
    if(i1 == 0) {
      // charsetto="UTF-8", charsetfrom="ISO-8859-1"|locale
      // GEHT NICHT mit UI_Ed_lcSet als charsetfrom !!!?
      p1 = g_convert (txbuf, *txlen, "UTF-8", "ISO-8859-1",
                      (gsize*)&i1, (gsize*)&i2, NULL);
        // printf(" _utf8_validate |%s| %d %d\n",UI_Ed_lcSet,i1,i2);
      if(p1 == NULL) {TX_Error("GUI_Ed_Write convert-ERR"); return -1;}
      if(i2 >= maxlen) {
        TX_Error("GUI_Ed_Write convert-EOM"); g_free(p1); return -1;}
      *txlen = i2;
      strcpy(txbuf, p1);
      g_free(p1);
    }
  }

  // provide text to editor
  gtk_text_buffer_set_text (wTx->text, txbuf, *txlen);
  // statt txlen -1 = bis '\0'.

  // curPos ans EOF setzen
  // set iter from cpos
  gtk_text_buffer_get_iter_at_offset (wTx->text, &it1, *txlen);

  // moves the "insert" and "selection_bound" marks simultaneously
  gtk_text_buffer_place_cursor (wTx->text, &it1);

  return 0;

}


//===================================================================
  void GUI_Ed_Focus (GIO_WinEd *wTx) {
//===================================================================
/// den Focus auf EditWindow

  // printf("GUI_Ed_Focus\n");

  // gtk_widget_set_sensitive (wTx->win, TRUE);

  gtk_widget_grab_focus (wTx->view);
  // gtk_widget_grab_focus (wTx->text);
  // gtk_widget_grab_focus (wTx->win);

  gtk_text_view_set_cursor_visible ((GtkTextView*)wTx->view, TRUE);

}


//=======================================================================
  void GUI_Ed_Init (void *parent, GIO_WinEd *wTx, void* funcnam, int mode) {
//=======================================================================
/// \code
/// 
/// view  for Focus
/// text  for all iterOper's
/// win   for packer
/// 
/// mode = 0: kein Lineumbruch
/// mode = 1: Lineumbruch
/// 
/// funcnam = NULL od CallBackroutine for every char entered or removed
/// 
///   GUI_Ed_Init (&winEd, NULL, 0);
///   gtk_container_add (GTK_CONTAINER(box0), winED.win);
///   gtk_widget_show (winED.win);
/// 
/// \endcode



  // GtkWidget *vpaned;
  int           i1;
  GtkWidget     *sw;
  GtkTextBuffer *buffer;
  GtkWidget     *EdView;


  // printf("GUI_Ed_Init \n");

  i1 = g_get_charset ((const char **)&UI_Ed_lcSet);  // i1=TRUE, wenn lcSet==UTF8.
    // printf(" charSet %d  |%s|\n",i1,UI_Ed_lcSet);
  if(i1 != 0) UI_Ed_lcSet = NULL;



  //----------------------------------------------------------------
  EdView = gtk_text_view_new ();

  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (EdView));

  gtk_text_buffer_set_text (buffer, "", -1);


  //----------------------------------------------------------------
  // vpaned = gtk_vpaned_new ();
  // gtk_container_set_border_width (GTK_CONTAINER(vpaned), 5);
  // // gtk_container_add (GTK_CONTAINER (*wtext), vpaned);
  sw = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
          GTK_POLICY_NEVER,          // hor
          GTK_POLICY_AUTOMATIC);     // vert
  // gtk_paned_add1 (GTK_PANED (vpaned), sw);
  // gtk_widget_show (vpaned);
  gtk_container_add (GTK_CONTAINER (sw), EdView);



  // wrap: GTK_WRAP_NONE GTK_WRAP_CHAR GTK_WRAP_WORD
  if(mode == 1)
    gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (EdView), GTK_WRAP_CHAR);
  else
    gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (EdView), GTK_WRAP_NONE);



  gtk_widget_show (sw);
  gtk_widget_show (EdView);


  wTx->view = EdView;    // Focus geht nur mit EdView
  wTx->text = buffer;    // buffer fuer alle iterOper's
  // wTx->win  = vpaned;
  wTx->win  = sw;


  gtk_text_view_set_editable ((GtkTextView*)EdView, TRUE);
  gtk_text_view_set_cursor_visible ((GtkTextView*)EdView, TRUE);  



  // Init Textfensterparameter
  // GUI_Ed_Init1 (wTx);


  // connect keyPress ..
  if (funcnam) {
    g_signal_connect (G_OBJECT (EdView),
                        "key-press-event",
                        G_CALLBACK (funcnam), NULL);
  }


      gtk_container_add (GTK_CONTAINER(parent), sw);
      gtk_widget_show (sw);
      gtk_widget_set_size_request (sw, 300, 600);





  return;

}


/*
//================================================================
  void GUI_Ed_Init1 (GIO_WinEd *wTx) {
//================================================================
/// \code
/// GUI_Ed_Init1           get attributes of Editwindow (textsize, ..)
/// ACHTUNG: changed: window nicht buffer !!
///  geht erste nach gtk_widget_show
/// \endcode

  GtkStyle  *style_act;
  GdkFont   *wFont;

  // Style hat farben, Font GdkFont *font, BackgrndPixmap usw
  style_act = gtk_widget_get_style (wTx->view);

  wFont = gtk_style_get_font (style_act);
  // printf(" ascent=%d descent=%d\n",wFont->ascent,wFont->descent);
  UI_Ed_ln_sizY = wFont->ascent + wFont->descent;
  // printf("  UI_Ed_ln_sizY = %d\n",UI_Ed_ln_sizY);



  // Mitte Window als Offset; geht aber erst viel spaeter !
  // printf("pgSiz=%f\n",GTK_ADJUSTMENT(GTK_TEXT(text)->vadj)->page_size);
  // printf("pgIncr=%f\n",GTK_ADJUSTMENT(GTK_TEXT(text)->vadj)->page_increment);
  // UI_Ed_ln_offY = GTK_ADJUSTMENT(GTK_TEXT(text)->vadj)->page_size;
  // UI_Ed_ln_offY = UI_Ed_ln_sizY * 10.;
  // printf("UI_Ed_ln_offY=%f\n", UI_Ed_ln_offY);


  // liefert size vom ganzen Win; Mist.
  // printf(" height=%d\n", GTK_WIDGET(text)->allocation.height);

}
*/



//================== EOF =========================================
